package com.jaws.core.common.log;

import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.springframework.util.ReflectionUtils.FieldCallback;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * 日志包装类
 *
 * @author maojian
 * @date 2017-05-12 09:05:41
 * @since 1.0.0
 */
public class Log {
	/**
	 * 敏感信息过滤开关
	 */
	protected static boolean isSansInfoCrytoEnable = false;

	/**
	 * 操作类型
	 */
	private String operation;

	/**
	 * 日志信息
	 */
	private String message = EMPTY_STR;

	/**
	 * 额外的参数
	 */
	private Map<String, Object> params = new HashMap<String, Object>();

	/**
	 * 日志格式 [message] [operation],{key1=value1,key2=value2,key3=value3}
	 */
	private static final String LOG_FORMAT = "%s|%s|%s";

	/**
	 * 空字符串
	 */
	private static final String EMPTY_STR = "";

	/**
	 * 存放包含敏感信息对象object的map  存储格式<object.class,<fieldname,annotation.class>>
	 */
	protected static Map<Class<?>, Map<String, Class<?>>> sensClassMap = Maps.newHashMap();

	/**
	 * 存放敏感信息的注解类annotation.class
	 */
	protected static Set<Class<?>> annotationClassed = Sets.newHashSet();

	private ValueFilter valueFilter = new ValueFilter() {
		@Override
		public Object process(Object o, String propertyName, Object propertyValue) {
			Set<Class<?>> sensClasses = sensClassMap.keySet();
			for(Class<?> cls : sensClasses){
				if(cls.isAssignableFrom(o.getClass())){
					Map<String, Class<?>> saFields = sensClassMap.get(cls);
					if (null != saFields && saFields.containsKey(propertyName)) {
						return LogSensConverter.convert((String) propertyValue, saFields.get(propertyName));
					}
				}
			}
			
			return propertyValue;
		}
	};

	/**
	 * @param operation 操作
	 */
	public Log(String operation) {
		this.operation = operation;
	}

	/**
	 * 创建Log对象
	 *
	 * @param op 操作
	 * @return
	 */
	public static Log op(String op) {
		return new Log(op);
	}

	/**
	 * @param message 信息
	 * @return
	 */
	public Log msg(String message) {
		this.message = message;
		return this;
	}

	/**
	 * 
	 * @param message 信息
	 * @return
	 */
	public Log msg(String message, Object... args) {
		this.message = MessageFormat.format(message, args);
		return this;
	}
	
	/**
	 * 键值对
	 *
	 * @param key key
	 * @param value 值
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Log kv(String key, final Object value) {
		params.put(key, JSONObject.toJSONString(value, valueFilter));
		return this;
	}

	/**
	 * @param maps
	 * @return
	 */
	public Log kvs(Map<String, Object> maps) {
		params.putAll(maps);
		return this;
	}

	@Override
	public String toString() {
		String toStr = String.format(LOG_FORMAT, message, params.toString(), operation);
		return toStr;
	}

}
